//Package models 商品数据处理
package models

import (
	"ShopSupplierApi/models/mysql"
	"ShopSupplierApi/utils"
	dbsql "database/sql"
	"time"
)

//ProductStatusType 商品状态
type ProductStatusType int

const (
	//ProductStatusTypeAll 所有
	ProductStatusType_All ProductStatusType = iota
	//ProductStatusTypeSale 销售中的
	ProductStatusType_Sale
	//ProductStatusTypeProvide 供应
	ProductStatusType_Provide
	//ProductStatusTypeWaring 库存警报的
	ProductStatusType_Waring
	//ProductStatusTypeDown 下架的
	ProductStatusType_Down
	//ProductStatusTypeWaitSale 待售
	ProductStatusType_WaitSale
)

//枚举说明
func (pt ProductStatusType) String() string {
	switch pt {
	case ProductStatusType_Sale:
		return "销售中的"
	case ProductStatusType_Provide:
		return "供应"
	case ProductStatusType_Waring:
		return "库存警报的"
	case ProductStatusType_Down:
		return "下架的"
	case ProductStatusType_WaitSale:
		return "待售"
	default:
		return "所有"
	}
}

//Product 商品列表信息
type Product struct {
	ID           *int64   //货品ID
	Name         *string  //名称
	SpecInfo     *string  //规格
	Price        *float64 //价格
	Bn           *string  //BN
	Store        *int     //库存
	Freez        *int     //锁定库存
	BrandName    *string  //品牌名称
	CatName      *string  //分类
	DefaultPrice *float64 //默认价格
}

//productInformationSQL 生成查询货品信息的SQL语句
//param supplierID uint64 供应商ID
func productInformationSQL(supplierID uint64) string {
	if supplierID == 0 {
		return " SELECT a.product_id,a.`name` NAME,a.spec_info,a.price,a.bn bn,a.store,a.freez,c.brand_name,d.cat_name catname,a.price default_price " +
			" FROM sdb_b2c_products a LEFT JOIN sdb_b2c_goods e ON a.goods_id = e.goods_id " +
			" LEFT JOIN sdb_b2c_brand c ON e.brand_id = c.brand_id " +
			" LEFT JOIN sdb_b2c_goods_cat d ON e.cat_id = d.cat_id WHERE 0 = ? "

	}
	return " SELECT a.product_id,a.product_name name,b.spec_info,a.price,a.product_bn bn,a.store,a.freez,c.brand_name,d.cat_name catname,b.price default_price " +
		" FROM lcf_supplier_products a LEFT JOIN sdb_b2c_products b ON a.product_id = b.product_id " +
		" LEFT JOIN sdb_b2c_goods e ON b.goods_id = e.goods_id " +
		" LEFT JOIN sdb_b2c_brand c ON e.brand_id = c.brand_id LEFT JOIN sdb_b2c_goods_cat d ON e.cat_id = d.cat_id WHERE a.supplier_id = ? "
}

//ProductList 货品列表
//param supplier_id uint64 供应商ID
//param search string 商品搜索关键词
//param status ProductStatusType 商品状态
//param p *Page 数据分页信息
func ProductList(supplierID uint64, search string, status ProductStatusType, p *Page) []Product {
	args := []interface{}{supplierID}
	var sql string
	if status != ProductStatusType_All {
		sql = productInformationSQL(supplierID)
		if search != "" {
			if supplierID == 0 {
				search = "%" + search + "%"
				sql += " AND (a.`name` like ? OR a.bn like ? OR a.spec_info like ? ) "
				args = append(args, search, search, search)
			} else {
				search = "%" + search + "%"
				sql += " AND  (a.product_name like ? OR a.product_bn like ? OR a.spec_info like ? ) "
				args = append(args, search, search, search)
			}
		}
	} else {
		sql = "SELECT a.product_id,a.default_name name,a.spec_info,a.price,a.bn,a.store,a.freez,c.brand_name,d.cat_name catname,a.default_price " +
			" FROM lcf_b2c_products a " +
			" LEFT JOIN sdb_b2c_goods b ON a.goods_id = b.goods_id " +
			" LEFT JOIN sdb_b2c_brand c ON b.brand_id = c.brand_id LEFT JOIN sdb_b2c_goods_cat d ON b.cat_id = d.cat_id WHERE 0 = ? "
		if search != "" {
			search = "%" + search + "%"
			sql += " AND (a.`name` like ? OR a.bn like ? OR a.spec_info like ? ) "
			args = append(args, search, search, search)
		}
	}
	switch status {
	case ProductStatusType_Down:
		sql += " AND a.marketable = 'false' "
	case ProductStatusType_Sale:
		if supplierID != 0 {
			sql += " AND a.disable = 0 "
		}
	case ProductStatusType_Waring:
		sql += " AND a.store < 10 "
	case ProductStatusType_WaitSale:
		if supplierID != 0 {
			sql += " AND a.disable = 1"
		}
	}
	result := []Product{}
	err := mysql.RowsCallbackResult(p.SQL(sql), func(rows *dbsql.Rows) {
		for rows.Next() {
			var product Product
			err := rows.Scan(&product.ID, &product.Name, &product.SpecInfo, &product.Price,
				&product.Bn, &product.Store, &product.Freez, &product.BrandName, &product.CatName, &product.DefaultPrice)
			if err == nil {
				result = append(result, product)
			} else {
				utils.Logger.Error(err.Error())
			}
		}
	}, args...)
	if err != nil {
		utils.Logger.Error(sql, err.Error())
	}
	p.Rows = int64(len(result))
	p.CountRows(sql, args)
	return result
}

//ProductInfo 货品信息
//param supplierID uint64	供应商ID
//param productID	uint64	货品ID
func ProductInfo(supplierID uint64, productID uint64) *Product {
	sql := productInformationSQL(supplierID)
	sql += " AND a.product_id = ? "
	row, err := mysql.Row(sql, supplierID, productID)
	if err != nil {
		utils.Logger.Error(sql, err.Error())
		return nil
	}
	product := &Product{}
	err = row.Scan(&product.ID, &product.Name, &product.SpecInfo, &product.Price,
		&product.Bn, &product.Store, &product.Freez, &product.BrandName, &product.CatName, &product.DefaultPrice)
	if err != nil {
		utils.Logger.Error(err.Error())
		return nil
	}
	return product
}

//SupplierSupplyProduct 供应商供应商品
//param supplierID uint64 供应商ID
//param productID uint64 货品ID
//param price float64 商品价格
//param productName string 自定义货品名称
//param productBn string 自定义货品BN
func SupplierSupplyProduct(supplierID uint64, productID uint64, price float64, productName string, productBn string) (bool, string) {
	//检测货品是否已经供应
	sql := "SELECT count(1) c FROM lcf_supplier_products WHERE supplier_id = ? AND product_id = ? "
	row, err := mysql.Row(sql, supplierID, productID)
	if err != nil {
		utils.Logger.Error(err.Error())
		return false, "数据操作异常"
	}
	var c int
	err = row.Scan(&c)
	if err != nil {
		utils.Logger.Error(err.Error())
		return false, "数据读取异常"
	}
	if c > 0 {
		return false, "您已经供应该商品,无法重复供应."
	}
	//检测自定义货号/货名是否被重复使用
	sql = "SELECT product_name FROM lcf_supplier_products WHERE ( product_bn = ?  OR product_id = ? ) AND supplier_id = ? "
	row, err = mysql.Row(sql, productBn, productName, supplierID)
	if err != nil {
		utils.Logger.Error(err.Error())
		return false, "数据操作异常"
	}
	var pName string
	err = row.Scan(&pName)
	if err == nil {
		return false, "该货号或货名已被使用在[" + pName + "]上,请使用新货号"
	}
	//开始供应货品
	err = mysql.Transaction(func(tx *dbsql.Tx) error {
		sql = "INSERT INTO lcf_supplier_products(supplier_id,product_id,product_name,product_bn,price,last_modify) " +
			" VALUES ( ?,?,?,?,?,? )"
		_, err = tx.Exec(sql, supplierID, productID, productName, productBn, price, time.Now())
		if err != nil {
			utils.Logger.Error(err.Error())
			return err
		}
		sql = "INSERT INTO lcf_supplier_productPriceChange(price,createtime,supplier_id,product_id,description) " +
			" VALUES( ?,?,?,?,? )"
		_, err = tx.Exec(sql, price, time.Now(), supplierID, productID, "首次报价")
		if err != nil {
			utils.Logger.Error(err.Error())
			return err
		}
		return nil
	})
	if err != nil {
		return false, "数据保存失败"
	}
	return true, ""
}

//SupplierChangeStore 供应商修改库存
//param supplierID uint64 供应商ID
//param productID uint64 货品ID
//param singleprice float64 采购单价
//param nums int 数量
//param description string 备注
func SupplierChangeStore(supplierID uint64, productID uint64, singleprice float64, nums int32, description string) (bool, string) {
	if nums == 0 { //数量为0无需更新直接返回成功
		return true, ""
	}
	args := map[string]interface{}{"supplier_id": supplierID, "product_id": productID}
	sql := "SELECT store,freez FROM lcf_supplier_products WHERE supplier_id = @supplier_id AND product_id = @product_id " //获取原本数据
	sql, params, err := mysql.ParseSQL(sql, args)
	if err != nil {
		return false, err.Error()
	}
	row, err := mysql.Row(sql, params...)
	if err != nil {
		utils.Logger.Error(err.Error())
		return false, "供应商品不存在"
	}
	var store int32
	var freez int32
	err = row.Scan(&store, &freez)
	if err != nil {
		utils.Logger.Error(err.Error())
		return false, "供应商品不存在"
	}
	store = store + nums
	if store < freez {
		return false, "退货数量不能大于实际可用数量,请检查"
	}
	err = mysql.Transaction(func(tx *dbsql.Tx) error {
		sql = "INSERT INTO lcf_supplier_purchase (single_price,store,nums,discription,supplier_id,product_id,createtime,lastmodify) " +
			" VALUES( @singleprice,@store,@store,@discription,@supplier_id,@product_id,@createtime,@lasttime )"
		args["singleprice"] = singleprice
		args["store"] = store
		args["discription"] = description
		args["createtime"] = time.Now()
		args["lasttime"] = time.Now()
		sql, params, err = mysql.ParseSQL(sql, args)
		if err != nil {
			return err
		}
		_, err = tx.Exec(sql, params...)
		if err != nil {
			utils.Logger.Error(err.Error())
			return err
		}
		sql = "UPDATE lcf_supplier_products SET store = @store WHERE product_id = @product_id AND supplier_id = @supplier_id "
		sql, params, err = mysql.ParseSQL(sql, args)
		if err != nil {
			return err
		}
		_, err = tx.Exec(sql, params...)
		if err != nil {
			utils.Logger.Error(err.Error())
		}
		return err
	})
	if err != nil {
		return false, "数据保存失败"
	}
	return true, ""
}

//SupplierMarketableChange 供应商货品上下架
//param supplierID uint64 供应商ID
//param productID uint64 货品ID
//param value bool 上架下架
func SupplierMarketableChange(supplierID uint64, productID uint64, value bool) bool {
	marketable := "false"
	if value {
		marketable = "true"
	}
	sql := "UPDATE lcf_supplier_products SET marketable = '" + marketable + "' WHERE product_id = ? AND supplier_id = ? "
	_, err := mysql.Exec(sql, productID, supplierID)
	if err != nil {
		utils.Logger.Error(err.Error())
		return false
	}
	return true
}

//SupplierUpdatePrice 供应商更改商品价格
//param supplierID uint64 供应商ID
//param productID uint64 货品ID
//param price float64 新价格
//param description string 备注
func SupplierUpdatePrice(supplierID uint64, productID uint64, price float64, description string) bool {
	err := mysql.Transaction(func(tx *dbsql.Tx) error {
		sql := "UPDATE lcf_supplier_products SET price = ? WHERE product_id = ? AND supplier_id = ? "
		_, err := tx.Exec(sql, price, productID, supplierID)
		if err != nil {
			return err
		}
		sql = "INSERT INTO lcf_supplier_productPriceChange(price,createtime,supplier_id,product_id,description) " +
			" VALUES( ?,?,?,?,? )"
		_, err = tx.Exec(sql, price, time.Now(), supplierID, productID, description)
		if err != nil {
			utils.Logger.Error(err.Error())
		}
		return err
	})
	return err == nil
}

//ProductSaleLocal 货品销售区域统计
//param supplierID uint64 供应商ID
//param productID uint64 货品ID
//param localType int 地区标记[0=省,1=市,2=县]
//param regionID int 上一级地区ID
func ProductSaleLocal(suppplierID uint64, productID uint64, localType int, regionID int) []map[string]interface{} {
	sql := "SELECT sum(a.nums) nums,c.region_id,c.local_name FROM sdb_b2c_order_items a LEFT JOIN orders_extinfo b ON a.order_id = b.order_id " +
		" LEFT JOIN sdb_ectools_regions c ON "
	if localType == 2 {
		sql += " b.county = c.region_id "
	} else if localType == 1 {
		sql += " b.city = c.region_id "
	} else {
		sql += " b.province = c.region_id "
	}
	sql += " LEFT JOIN sdb_b2c_orders d ON a.order_id = d.order_id WHERE d.supplier_id = @supplier_id "
	sql += " AND a.product_id = @product_id AND b.order_id is not NULL AND d.pay_status = \"1\" "
	if localType == 2 {
		sql += " AND b.city = @region_id GROUP BY county "
	} else if localType == 1 {
		sql += " AND b.province = @region_id GROUP BY city "
	} else {
		sql += " GROUP BY b.provinc "
	}
	sql, params, err := mysql.ParseSQL(sql, map[string]interface{}{"product_id": productID, "supplier_id": suppplierID, "region_id": regionID})
	if err != nil {
		utils.Logger.Error(err.Error())
		return nil
	}
	var result []map[string]interface{}
	err = mysql.RowsCallbackResult(sql, func(rows *dbsql.Rows) {
		var sum int
		var rg int
		var localName string
		for rows.Next() {
			e := rows.Scan(&sum, &rg, &localName)
			if e == nil {
				result = append(result, map[string]interface{}{"nums": sum, "region_id": rg, "local_name": localName})
			}
		}
	}, params...)
	if err != nil {
		utils.Logger.Error(err.Error())
		return nil
	}
	return result
}
